
namespace KlearTweet.Client.Search
{
    public class OmniBoxController
    {
        private readonly System.Collections.Generic.List<string> _history
            = new System.Collections.Generic.List<string>();

        private readonly System.Collections.ObjectModel.ObservableCollection<SearchItem> _searchItems
            = new System.Collections.ObjectModel.ObservableCollection<SearchItem>();

        private readonly DataProvider _dataProvider;
        private readonly Initialization.AccountsManager _accountsManager;
        private readonly System.Windows.Controls.AutoCompleteBox _omniBox;
        private bool _isChangingSelection;


        public OmniBoxController(DataProvider dataProvider, Initialization.AccountsManager accountsManager, Tab.TabHeader header)
        {
            _dataProvider = dataProvider;
            _accountsManager = accountsManager;
            _omniBox = header.OmniBox;
            _omniBox.Loaded += (s, e) => Initialize();

            header.OmniBoxDropDownToggleClicked += (s, e) => OnDropDownToggleClicked();
            dataProvider.SearchRequested += (s, e) => AddToHistory(e.Value);
        }


        private void Initialize()
        {
            _omniBox.KeyUp += (s, e) =>
            {
                if (e.Key == System.Windows.Input.Key.Enter)
                    _dataProvider.SearchAsync(_omniBox.Text);
            };

            _omniBox.ItemFilter = (text, obj) =>
            {
                if (string.IsNullOrEmpty(text))
                    return true;
                var item = obj as SearchItem;
                if (item == null)
                    return false;
                return (item.GetFullText().ToUpper(System.Globalization.CultureInfo.InvariantCulture) // TODO: Replace by better compare
                    .Contains(text.ToUpper(System.Globalization.CultureInfo.InvariantCulture)));
            };

            _omniBox.ItemsSource = _searchItems;
            _omniBox.SelectionChanged += (s, e) => OnSelectionChanged();
            _omniBox.Populating += (s, e) => OnPopulating();
        }


        private void OnSelectionChanged()
        {
            if (_isChangingSelection)
            {
                _isChangingSelection = false;
                return;
            }

            var item = _omniBox.SelectedItem as SearchItem;
            if (item != null && !_omniBox.IsDropDownOpen) // Don't run the search while the user navigates the DropDown (using the keyboard) // TODO: Makes clicking on an item not run the search (the DropDown is still open)
                _dataProvider.SearchAsync(item.SearchText);
        }


        private void AddToHistory(string searchText)
        {
            if (_history.Count > 0 && _history[0] == searchText)
                return; // This occurs when clicking a hyperlink in a TweetView (it sets the _omniBox.Text which triggers OnSelectionChanged()) // TODO: Find a better solution

            _isChangingSelection = true;
            _omniBox.Text = searchText; // Required when the user clicks on a shortcut button // TODO: This is not elequant

            if (!string.IsNullOrEmpty(searchText))
                _history.Insert(0, searchText);
            if (_history.Count > 5) // Max // TODO: Should keep the full history for search, but only display the top 5
                _history.RemoveRange(5, _history.Count - 5);
        }


        private void OnPopulating()
        {
            // Refresh the list
            _searchItems.Clear();
            foreach (var history in _history)
                _searchItems.Add(SearchItem.FromHistoryPoint(history));

            foreach (var account in _accountsManager.GetAccounts())
            {
                _searchItems.Add(SearchItem.From(account, SearchItem.FriendsTimeline));
                _searchItems.Add(SearchItem.From(account, SearchItem.UserTimeline));
            }

            _searchItems.Add(SearchItem.FromHome());
        }


        private void OnDropDownToggleClicked()
        {
            _omniBox.Focus();
            _omniBox.IsDropDownOpen = !_omniBox.IsDropDownOpen;
        }
    }
}